package com.bridgeintelligent.tag.bulkload.service.core.issue;

import com.bridgeintelligent.tag.bulkload.api.BulkLoadException;
import com.bridgeintelligent.tag.bulkload.api.issue.CustomersChannel;
import com.bridgeintelligent.tag.bulkload.api.issue.IssueLog;
import com.bridgeintelligent.tag.bulkload.api.issue.IssueTaskLog;
import com.bridgeintelligent.tag.bulkload.api.utils.TarUtils;
import com.bridgeintelligent.tag.bulkload.service.config.IssueConfiguration;
import com.bridgeintelligent.tag.remotefile.RemoteFileHandler;
import com.bridgeintelligent.tag.utils.DateHelper;
import com.wayneleo.quickstart.framework.ExceptionCode;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @description
 * @author: grp 2021-03-06 14:32
 **/
@Service
@AllArgsConstructor
@Slf4j
public class IssueIftService {
    // VASP_任务标识_yyyymmdd.zip VASP_任务标识_yyyymmdd.txt VASP_任务标识_yyyymmdd.ok
    private static final String LOCAL_FILE_TEMP_FORMAT = "/data/issue/%s";
    // ift隐藏目录
    private static final String IFT_STATUS_FORMAT = "%s/.ift";
    private static final String LOCAL_FILE_ZIP_FORMAT = "%s_%s_%s";
    private static final String FILE_OK_FORMAT = "ok";
    private static final String FILE_ZIP_FORMAT = "zip";
    private static final String FILE_TAR_FORMAT = "tar";
    private static final String FILE_NAME_FORMAT = "%s.%s";
    private static final String CHANNEL_PATH_DATE_FORMAT = "/%s/%s";
    private static final String CHANNEL_PATH_FORMAT = "/%s";
    private static final String CLEAR_FILE_PATH_FORMAT = "%s/%s";

    private static final String CPAAS = "/cpaas";
    //新增应急目录文件传送规则
    private static final String NEW_LOCAL_FILE_ZIP_FORMAT = "IFT_Emergency%s_%s";

    private final RemoteFileHandler remoteFileHandler;
    private final IssueConfiguration issueConfiguration;

    public String upload(String dataDate, IssueTaskLog issueTaskLog,
                         IssueLog issueLog, CustomersChannel customersChannel, File... source) throws IOException, ParseException {
        //先判断发送类型，是走常规目录false还是应急目录true
        boolean retry = isRetry(issueLog.getIsRetry(), dataDate);
        // 文件名称前缀
        String fileName = getTempPath(issueTaskLog, dataDate, customersChannel, LOCAL_FILE_ZIP_FORMAT);
        if (retry){
            fileName = String.format(NEW_LOCAL_FILE_ZIP_FORMAT, DateHelper.currentDateTime(DateHelper.PATTERN_DATE_8),fileName);
        }
        // 压缩文件名称
        //String zipFileName = String.format(FILE_NAME_FORMAT,fileName,FILE_ZIP_FORMAT);
        String zipFileName = String.format(FILE_NAME_FORMAT,fileName,FILE_TAR_FORMAT);
        // 本地压缩文件全路径
        String zipPath = String.format(LOCAL_FILE_TEMP_FORMAT,zipFileName);
        // 压缩
        //ZipUtils.zipMore(zipPath, source);
        TarUtils.tarMore(zipPath,source);
        // 压缩文件远程上传
        String sendPath = getIftPath(issueLog, customersChannel, dataDate);
        //1.检查和清理文件
        checkAndClear(sendPath,fileName);
        //2.上传压缩文件
        String remoteFile = remoteFileHandler.uploadByPath(new File(zipPath).getAbsolutePath(), sendPath
                , zipFileName);
        //3.创建ok文件
        String okFileName = String.format(FILE_NAME_FORMAT,fileName,FILE_OK_FORMAT);
        String okPath = String.format(LOCAL_FILE_TEMP_FORMAT,zipFileName);
        File okFile = new File(okPath);
        if(!okFile.exists()){
            okFile.createNewFile();
        }
        remoteFileHandler.uploadByPath(okFile.getAbsolutePath(), sendPath
                , okFileName);
        return remoteFile;
    }

    private void checkAndClear(String sendPath,String fileName) {
        String iftStatusPath = String.format(IFT_STATUS_FORMAT,sendPath);
        clear(fileName, sendPath);
        clearIft(fileName, iftStatusPath);
    }

    private void clear(String fileName, String path) {
        File queryPath = new File(path);
        if (queryPath.exists() && queryPath.isDirectory()){
            //找出下面所有的文件或者文件夹名称
            String[] list = queryPath.list();
            for (String name:list) {
                if (StringUtils.startsWith(name,fileName)){
                    File file = new File(String.format(CLEAR_FILE_PATH_FORMAT,queryPath,name));
                    file.delete();
                }
            }
        }
    }
    private void clearIft(String fileName, String path) {
        File queryPath = new File(path);
        if (queryPath.exists() && queryPath.isDirectory()){
            //找出下面所有的文件或者文件夹名称
            String[] list = queryPath.list();
            for (String name:list) {
                if (name.contains(fileName)){
                    File file = new File(String.format(CLEAR_FILE_PATH_FORMAT,queryPath,name));
                    file.delete();
                }
            }
        }
    }

    private String getIftPath(IssueLog issueLog, CustomersChannel customersChannel, String dataDate) {
        // 重试走应急
        if(StringUtils.equals(issueLog.getIsRetry(),"1")||
                StringUtils.compare(getDatePath(), dataDate)>0){
            return issueConfiguration.getIftEmergencyPath()+String.format(CHANNEL_PATH_FORMAT,
                    customersChannel.getTransferPath())+CPAAS;
        }
        return issueConfiguration.getIftPath()+String.format(CHANNEL_PATH_DATE_FORMAT,
                customersChannel.getTransferPath(), dataDate);
    }

    private boolean isRetry(String isRetry,String dataDate){
        // 重试走应急
        if(StringUtils.equals(isRetry,"1") || StringUtils.compare(getDatePath(), dataDate)>0){
            return true;
        }
        return false;
    }

    /**
     * 正常的发送路径
     */
    private String getDatePath(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(calendar.DATE, -3);
        return sdf.format(calendar.getTime());
    }

    /**
     * 临时目录
     * @param issueTaskLog
     * @param date
     * @param customersChannel
     * @param localFileFormat
     * @return
     * @throws ParseException
     */
    public String getTempPath(IssueTaskLog issueTaskLog, String date, CustomersChannel customersChannel,
                              String localFileFormat) throws ParseException {
        return String.format(localFileFormat, customersChannel.getChannelId(), issueTaskLog.getIssueKey(),
                date);
    }

    /**
     * 实际数据日期
     * @param dataDate
     * @return
     * @throws ParseException
     */
    public String getDate(String dataDate) throws ParseException {
        if(StringUtils.length(dataDate)==8){
            return dataDate;
        }
        if(StringUtils.length(dataDate)==6){
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMM");
            Date parse = sdf1.parse(dataDate);
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd");
            Calendar cal = Calendar.getInstance();
            cal.setTime(parse);
            int value = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
            cal.set(Calendar.DAY_OF_MONTH, value);
            Date time = cal.getTime();
            return sdf2.format(time);
        }
        throw new BulkLoadException(new ExceptionCode(999,String.format("数据时间错误【%S】",dataDate)));
    }
}
